package com.infore.siteManagement.OutSide.Service.Impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import com.infore.siteManagement.OutSide.Service.IOutsideService;
import com.infore.siteManagement.OutSide.dto.StationInfoDto;
import com.infore.siteManagement.constant.Constants;
import com.infore.siteManagement.entity.Area;
import com.infore.siteManagement.entity.Equipment;
import com.infore.siteManagement.entity.Project;
import com.infore.siteManagement.entity.Station;
import com.infore.siteManagement.entity.otherEntity.Instructions;
import com.infore.siteManagement.entity.otherEntity.Protocol;
import com.infore.siteManagement.enums.ResultStatus;
import com.infore.siteManagement.repository.IAreaRespository;
import com.infore.siteManagement.repository.IEquipmentRepository;
import com.infore.siteManagement.repository.IInstructionsIdRespository;
import com.infore.siteManagement.repository.IProjectAndEquipmentRepository;
import com.infore.siteManagement.repository.IProtocolIdRespository;
import com.infore.siteManagement.repository.IStationRepository;
import com.infore.siteManagement.repository.IStationVievRepository;
import com.infore.siteManagement.repository.IndexRespository;
import com.infore.siteManagement.select.dto.QueryParamDto;
import com.infore.siteManagement.select.util.QueryCondition;
import com.infore.siteManagement.service.IAreaService;
import com.infore.siteManagement.service.IFilterService;
import com.infore.siteManagement.service.equipment.IEquipSampleService;
import com.infore.siteManagement.util.ArrayUtils;
import com.infore.siteManagement.util.JsonUtils;
import com.infore.siteManagement.util.ObjectMapperUtil;
import com.infore.siteManagement.util.ResultEntity;

/**
 * 暴露服务实现层
 * 
 * @author 刘乐法
 *
 *
 */
@Service
public class IOutsideServiceImpl implements IOutsideService {

	@Autowired
	private IStationRepository iStationRepository;
	@Autowired
	private IProtocolIdRespository iProtocolIdRespository;
	@Autowired
	private IInstructionsIdRespository iInstructionsIdRespository;
	@Autowired
	private IAreaRespository iAreaRespository;
	@Autowired
	private IndexRespository indexRespository;
	@Autowired
	private IEquipmentRepository iEquipmentRepository;
	@Autowired
	private IProjectAndEquipmentRepository iProjectAndEquipmentRepository;
	@Autowired
	private IStationVievRepository iStationVievRepository;
	@Autowired
	private IEquipSampleService iEquipSampleService;
	@Autowired
	private ObjectMapperUtil objectMapperUtil;
	@Autowired
	private IFilterService iFilterService;
	@Autowired
    private IAreaService iAreaService;

	public ResultEntity stationInfo(String protocolDataId) {
		// 通过协议id查找中间类ProtocolId
		Protocol protocol = iProtocolIdRespository.findOneByProtocolId(protocolDataId);
		if (org.springframework.util.StringUtils.isEmpty(protocol)) {
			return new ResultEntity(ResultStatus.SUCCESS, "数据对象为空").setDataList(null);
		}
		// 中间类ProtocolId维护了站点信息 多对多
		Set<Station> stations = protocol.getStation_Protocol();
		List<Station> list = new ArrayList<Station>(stations);
		return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setDataList(list);
	}

	public ResultEntity equipmentInfo(String instructionsId) {
		// TODO Auto-generated method stub
		// 通过指令id查找中间类InstructionsId
		Instructions instructions = iInstructionsIdRespository.findOneByInstructionsId(instructionsId);
		if (org.springframework.util.StringUtils.isEmpty(instructions)) {
			return new ResultEntity(ResultStatus.SUCCESS, "数据对象为空").setDataList(null);
		}
		// 中间类InstructionsId维护了设备信息 多对多
		Set<Equipment> equipments = instructions.getEquipment_Instructions();
		List<Equipment> list = new ArrayList<Equipment>(equipments);
		return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setDataList(list);
	}

	public ResultEntity stationInfoAudit(List<String> stationMnList) {
		if (stationMnList == null || stationMnList.size() < 0) {
			return new ResultEntity(ResultStatus.SUCCESS, "数据为空站点不存在").setDataList(null);
		}
		// 通过stationMn拿到站点集合
		List<Station> stations = iStationRepository.findAllByStationMnIn(stationMnList);
		// 判断数据库中是否有站点对象
		List<StationInfoDto> stationInfoDtos = new ArrayList<StationInfoDto>();
		if (stations == null || stations.size() == 0) {
			return new ResultEntity(ResultStatus.SUCCESS, "数据为空站点不存在").setDataList(stationInfoDtos);
		}
		List<String> areaCodes = stations.stream().map(l -> l.getArea().getAreaCode()).collect(Collectors.toList());
		// 通过区域code得到省市区域
		//List<Area> areas = iAreaRespository.findByAreaCodeIn(areaCodes);
		List<Area> areas = iAreaService.areaParents(String.join(",", areaCodes));
		String basin = null;
		for (Station station : stations) {
			StationInfoDto stationInfoDto = new StationInfoDto();
			stationInfoDto.setDataFrequency(station.getDataFrequency());
			stationInfoDto.setStationMn(station.getStationMn());
			stationInfoDto.setStationName(station.getStationName());
			stationInfoDto.setStationCompany(station.getOperCompanyName());
			stationInfoDto.setLatitude(station.getLatitude());
			stationInfoDto.setLongitude(station.getLongitude());
			basin = station.getBasinn() == null ? null : station.getBasinn().getBasinnName();
			stationInfoDto.setRiverBasin(basin);
			stationInfoDto.setStationType(station.getStationType1());
			for (Area area : areas) {
				// 站点维护的code是等级（市）
				if (area.getAreaId().equals(station.getArea().getAreaId())) {
					stationInfoDto.setStationProvin(area.getAreaName());
					// 站点维护的area对应的getParentId维护的上一级（省） 当前站点对应区域的父id code=查询到的区域code 则为对应的父区域
				} else if (area.getAreaCode().equals(station.getArea().getParentId())) {
					stationInfoDto.setStationCity(area.getAreaName());
				}
			}
			stationInfoDtos.add(stationInfoDto);
		}
		return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setDataList(stationInfoDtos);
	}

	public ResultEntity projectInfoAllAudit() {
		Sort sort = new Sort(Sort.Direction.ASC, "sortIndex");
		List<Project> list = indexRespository.findAll(sort);
		return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setDataList(list);
	}

	/**
	 * 通过因子编码得到因子信息
	 */
	public ResultEntity proiectInfoAlarm() {
		List<Project> projects = indexRespository.findAll();
		Map<String, Project> resultMap = new HashMap<String, Project>();
		for (Project project : projects) {
			resultMap.put(project.getProjectCode(), project);
		}
		return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setInfo(resultMap);
	}

	public ResultEntity queryEquipments(String stationMn) {
		List<String> mnList = ArrayUtils.stringToList(stationMn);
		List<String> eqList = iEquipmentRepository.findIdsByStationMn(mnList);
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		try {
			list = iProjectAndEquipmentRepository.selectEquipmentFive(eqList);
		} catch (Exception e) {
			return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setDataList(list);
		}
		return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setDataList(list);
	}

	@SuppressWarnings({ "unchecked", "serial", "rawtypes" })
	public ResultEntity queryStationMnByInfo(String provinceId, String basinnId, String stationClassifyId,
			String stationTypeId, String operCompanyId, String stationName,String userId,
			String platfrom,String appCode,String admin) {
		List<Station> stations = iStationVievRepository.findAll(new Specification<Station>() {
			public Predicate toPredicate(Root<Station> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
				List<Predicate> predicates = new ArrayList<Predicate>();
				// 根据区域判断
				if (StringUtils.isNotBlank(provinceId)) {
					Join join = root.join("provinceId");
					predicates.add(criteriaBuilder.equal(join.get("areaId").as(String.class), provinceId));
				}
				if (StringUtils.isNotBlank(basinnId)) {
					Join join = root.join("basinn");
					predicates.add(criteriaBuilder.equal(join.get("basinnId").as(String.class), basinnId));
				}
				if (StringUtils.isNotBlank(stationClassifyId)) {
					Join join = root.join("stationClassify");
					predicates.add(
							criteriaBuilder.equal(join.get("stationClassifyId").as(String.class), stationClassifyId));
				}
				if (StringUtils.isNotBlank(stationTypeId)) {
					Join join = root.join("stationType");
					predicates.add(criteriaBuilder.equal(join.get("stationTypeId").as(String.class), stationTypeId));
				}
				if (StringUtils.isNotBlank(operCompanyId)) {
					predicates.add(criteriaBuilder.equal(root.get("operCompanyId"), operCompanyId));
				}
				// 模糊查询站点名
				if (StringUtils.isNotBlank(stationName)) {
					predicates.add(criteriaBuilder.like(root.get("stationName"), "%" + stationName + "%"));
				}
				//根据角色id筛选
//				Map<String, Object> roles = iFilterService.getStationIds(roleId);
//				Boolean isAdmin = (Boolean)roles.get("isAdmin");
//				if (!isAdmin) {
//					List<String> ids = new ArrayList<String>();
//					ids = (List<String>)roles.get("value");
//					predicates.add(root.get("stationId").in(ids));
//				}
				return query.where(predicates.toArray(new Predicate[predicates.size()]))
						.orderBy(criteriaBuilder.asc(root.get("sort"))).getRestriction();
			}
		});
		//根据用户id过滤
		List<String> ids = iFilterService.getStationIdByCookie(platfrom, appCode, userId, admin);
		stations = stations.stream().filter(f->ids.contains(f.getStationId().toString()))
				.collect(Collectors.toList());
		List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
		if (stations.size() > 0) {
			for (Station station : stations) {
				Map<String, Object> map = new HashMap<String, Object>();
				map.put("stationMn", station.getStationMn());
				map.put("areaName", station.getArea().getAreaName());
				map.put("basinnName", station.getBasinn().getBasinnName());
				map.put("stationRiver", station.getStationRiver());
				map.put("stationName", station.getStationName());
				result.add(map);
			}
		}
		return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setDataList(result);
	}

	public ResultEntity queryEquipNew(String stationMn) throws IOException {
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		// 封装调用通用查询
		QueryParamDto queryParamDto = JsonUtils.readJsonFromClassPath("/param/queryParam/queryEquipSamplPart.json",
				QueryParamDto.class);
		QueryCondition queryCondition = queryParamDto.getQueryCondition();
		List<String> content = new ArrayList<String>();
		content.add(stationMn);
		queryCondition.setContent(content);
		ResultEntity resultEntity = iEquipSampleService.query(queryParamDto);
		// 对结果集根据id分组
		List<Map<String, Object>> result = objectMapperUtil.getMapList(resultEntity);
		Map<String, List<Map<String, Object>>> gResulr = result.stream()
				.collect(Collectors.groupingBy(g -> g.get("id").toString()));
		// 遍历封装仪器的部分信息，--仪器名称（型号），仪器量程（检出限），分析方法，生产厂家，监测因子
		gResulr.forEach((g, glist) -> {
			if (glist.size() > 0) {
				List<String> projectName = glist.stream().map(m -> m.get("projects_projectName").toString())
						.collect(Collectors.toList());
				Map<String, Object> map = new HashMap<String, Object>();
				String ANALY_METHONS = glist.get(0).get("equipmentModel_analysisMethod").toString();
				String EQUIPMENT_ORANGE = glist.get(0).get("equipmentModel_detectionLimit").toString();
				String PROJECT_NAME = StringUtils.join(projectName, ",");
				String MANUFACTOR = glist.get(0).get("equipmentModel_woocu").toString();
				String EQUIPMENT_MODEL = glist.get(0).get("equipmentModel_equipmentName").toString();
				map.put("ANALY_METHONS", ANALY_METHONS);
				map.put("EQUIPMENT_ORANGE", EQUIPMENT_ORANGE);
				map.put("PROJECT_NAME", PROJECT_NAME);
				map.put("MANUFACTOR", MANUFACTOR);
				map.put("EQUIPMENT_MODEL", EQUIPMENT_MODEL);
				list.add(map);
			}
		});
		return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setDataList(list);
	}

}
